package com.example.houseitemmanagebackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.houseitemmanagebackend.dto.MessageDTO;
import com.example.houseitemmanagebackend.entity.Message;
import com.example.houseitemmanagebackend.entity.Users;
import com.example.houseitemmanagebackend.entity.Locations;
import com.example.houseitemmanagebackend.mapper.MessageMapper;
import com.example.houseitemmanagebackend.service.MessageService;
import com.example.houseitemmanagebackend.service.UserService;
import com.example.houseitemmanagebackend.service.LocationService;
import com.example.houseitemmanagebackend.vo.MessageVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.example.houseitemmanagebackend.utils.RedisCacheUtils;

/**
 * 消息服务实现类
 */
@Service
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {

    private static final Logger log = LoggerFactory.getLogger(MessageServiceImpl.class);

    @Autowired
    private UserService userService;

    @Autowired
    private LocationService locationService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    @Cacheable(value = "messageCache", key = "'messages:' + #locationId", unless = "#result.isEmpty()")
    public List<MessageVO> getMessages(Integer locationId) {
        // 构建查询条件
        LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();

        // 如果指定了位置ID，则按位置ID过滤
        if (locationId != null) {
            queryWrapper.eq(Message::getLocationId, locationId);
        }

        // 按创建时间降序排序
        queryWrapper.orderByDesc(Message::getCreateTime);

        // 查询消息数据
        List<Message> messageList = list(queryWrapper);

        // 转换为VO对象
        List<MessageVO> messageVOList = new ArrayList<>();
        for (Message message : messageList) {
            MessageVO messageVO = new MessageVO();
            BeanUtils.copyProperties(message, messageVO);
            messageVOList.add(messageVO);
        }

        return messageVOList;
    }

    @Override
    @Transactional
    @CacheEvict(value = "messageCache", allEntries = true)
    public boolean markAsRead(Long messageId) {
        Message message = getById(messageId);
        if (message == null) {
            return false;
        }

        // 只有未读的通知消息才需要标记为已读
        if (message.getIsRead() == 0) {
            message.setIsRead(1);
            return updateById(message);
        }

        return true;
    }

    @Override
    @Transactional
    @CacheEvict(value = "messageCache", allEntries = true)
    public boolean markAllAsReadByLocation(Integer locationId) {
        // 调用Mapper中的自定义方法
        int count = baseMapper.markAllAsReadByLocation(locationId);
        return count > 0;
    }

    @Override
    @Transactional
    @CacheEvict(value = "messageCache", allEntries = true)
    public Integer createMessage(MessageDTO messageDTO) {
        String actualUserName = "";
        Integer userId = null;
        Users user;
        // 得到用户名
        if (messageDTO.getUserId() != null) {
            userId = messageDTO.getUserId();
            user = userService.getById(userId);
            actualUserName = user.getUsername();
        }
        if ("login".equals(messageDTO.getSubType()) || "logout".equals(messageDTO.getSubType())) {

            List<Locations> userLocations = locationService.getLocationList(userId);
            Integer firstMessageId = null;

            if (userLocations != null && !userLocations.isEmpty()) {
                for (Locations loc : userLocations) {
                    Message locationSpecificMessage = new Message();
                    BeanUtils.copyProperties(messageDTO, locationSpecificMessage); // 复制userId, title, content,
                                                                                   // messageType, subType等
                    locationSpecificMessage.setCreateTime(LocalDateTime.now());
                    if (actualUserName != null) {
                        locationSpecificMessage.setUserName(actualUserName);
                    }
                    locationSpecificMessage.setLocationId(loc.getId()); // Locations.id is Integer
                    locationSpecificMessage.setLocationName(loc.getName());

                    // 活动类型消息不需要 isRead 和 priority，BeanUtils.copyProperties 会从DTO复制，
                    // 如果DTO中这些字段为默认值(0或null)，则保持即可。

                    save(locationSpecificMessage);

                    if (firstMessageId == null) {
                        firstMessageId = locationSpecificMessage.getId();
                    }
                }

                // 清除所有位置相关的消息缓存
                for (Locations loc : userLocations) {
                    try {
                        String cacheKey = "messages:" + loc.getId();
                        redisTemplate.delete(cacheKey);
                    } catch (Exception e) {
                        log.error("清除位置 {} 消息缓存失败: {}", loc.getId(), e.getMessage());
                        // 继续执行，不影响业务流程
                    }
                }

                return firstMessageId; // 返回创建的第一条消息的ID
            } else {
                // 用户没有关联的位置，为该用户创建一条通用的登录/登出消息
                Message userSpecificMessage = new Message();
                BeanUtils.copyProperties(messageDTO, userSpecificMessage);
                userSpecificMessage.setCreateTime(LocalDateTime.now());
                if (actualUserName != null) {
                    userSpecificMessage.setUserName(actualUserName);
                }
                // 如果DTO中包含locationId/locationName，它们将被复制过来。
                // 否则，这条消息将不关联特定位置。
                save(userSpecificMessage);

                // 清除全局消息缓存
                clearMessageCaches();

                return userSpecificMessage.getId();
            }

        } else {
            // 对于非登录/登出类型的消息（例如通知或其他活动）
            Message singleMessage = new Message();
            BeanUtils.copyProperties(messageDTO, singleMessage);
            singleMessage.setCreateTime(LocalDateTime.now());
            singleMessage.setUserName(actualUserName);
            if ("notification".equals(messageDTO.getMessageType())) {
                singleMessage.setIsRead(Objects.requireNonNullElse(messageDTO.getIsRead(), 0));
                singleMessage.setPriority(Objects.requireNonNullElse(messageDTO.getPriority(), 0));
            }
            save(singleMessage);

            // 清除相关位置的消息缓存
            if (singleMessage.getLocationId() != null) {
                try {
                    String cacheKey = "messages:" + singleMessage.getLocationId();
                    redisTemplate.delete(cacheKey);
                } catch (Exception e) {
                    log.error("清除位置 {} 消息缓存失败: {}", singleMessage.getLocationId(), e.getMessage());
                    // 继续执行，不影响业务流程
                }
            } else {
                // 如果消息不关联特定位置，清除所有消息缓存
                clearMessageCaches();
            }

            return singleMessage.getId();
        }
    }

    /**
     * 清除所有消息相关缓存
     */
    private void clearMessageCaches() {
        RedisCacheUtils.deleteByPattern(redisTemplate, "messageCache::messages:*");
    }
}